package cn.virens.mybatis.mapper.example.base;

import java.util.ArrayList;
import java.util.List;

import cn.virens.common.exception.APIException;
import cn.virens.mybatis.BaseEnum;

@SuppressWarnings("serial")
public abstract class AbstractExampleCriteriaCriterion<T> extends AbstractExampleCriteria {
	protected final List<T> criterionList = new ArrayList<>();

	public AbstractExampleCriteriaCriterion(boolean isOr, String condition, Object value1, Object value2) {
		super(isOr, condition, value1, value2);
	}

	public AbstractExampleCriteriaCriterion(boolean isOr, String condition, Object value1) {
		super(isOr, condition, value1);
	}

	public AbstractExampleCriteriaCriterion(boolean isOr, String condition) {
		super(isOr, condition);
	}

	public T andIsNull(String column) {
		return addCriterion(false, column + " IS NULL");
	}

	public T andIsNotNull(String column) {
		return addCriterion(false, column + " IS NOT NULL");
	}

	public T andEqualTo(String column, Object value) {
		return addCriterion(false, column + " =", value);
	}

	public T andNotEqualTo(String column, Object value) {
		return addCriterion(false, column + " <>", value);
	}

	public T andGreaterThan(String column, Object value) {
		return addCriterion(false, column + " >", value);
	}

	public T andGreaterThanOrEqualTo(String column, Object value) {
		return addCriterion(false, column + " >=", value);
	}

	public T andLessThan(String column, Object value) {
		return addCriterion(false, column + " <", value);
	}

	public T andLessThanOrEqualTo(String column, Object value) {
		return addCriterion(false, column + " <=", value);
	}

	public T andIn(String column, Iterable<?> values) {
		return addCriterion(false, column + " IN", values);
	}

	public T andNotIn(String column, Iterable<?> values) {
		return addCriterion(false, column + " NOT IN", values);
	}

	public T andBetween(String column, Object value1, Object value2) {
		return addCriterion(false, column + " BETWEEN", value1, value2);
	}

	public T andNotBetween(String column, Object value1, Object value2) {
		return addCriterion(false, column + " NOT BETWEEN", value1, value2);
	}

	public T andLike(String column, String value) {
		return addCriterion(false, column + " LIKE", value);
	}

	public T andNotLike(String column, String value) {
		return addCriterion(false, column + " NOT LIKE", value);
	}

	public T andCondition(String condition) throws APIException {
		return addCriterion(false, condition);
	}

	public T andCondition(String condition, Object value) throws APIException {
		return addCriterion(false, condition, value);
	}

	public T orIsNull(String column) {
		return addCriterion(true, column + " IS NULL");
	}

	public T orIsNotNull(String column) {
		return addCriterion(true, column + " IS NOT NULL");
	}

	public T orEqualTo(String column, Object value) {
		return addCriterion(true, column + " =", value);
	}

	public T orNotEqualTo(String column, Object value) {
		return addCriterion(true, column + " <>", value);
	}

	public T orGreaterThan(String column, Object value) {
		return addCriterion(true, column + " >", value);
	}

	public T orGreaterThanOrEqualTo(String column, Object value) {
		return addCriterion(true, column + " >=", value);
	}

	public T orLessThan(String column, Object value) {
		return addCriterion(true, column + " <", value);
	}

	public T orLessThanOrEqualTo(String column, Object value) {
		return addCriterion(true, column + " <=", value);
	}

	public T orIn(String column, Iterable<?> values) {
		return addCriterion(true, column + " IN", values);
	}

	public T orNotIn(String column, Iterable<?> values) {
		return addCriterion(true, column + " NOT IN", values);
	}

	public T orBetween(String column, Object value1, Object value2) {
		return addCriterion(true, column + " BETWEEN", value1, value2);
	}

	public T orNotBetween(String column, Object value1, Object value2) {
		return addCriterion(true, column + " NOT BETWEEN", value1, value2);
	}

	public T orLike(String column, String value) {
		return addCriterion(true, column + " LIKE", value);
	}

	public T orNotLike(String column, String value) {
		return addCriterion(true, column + " NOT LIKE", value);
	}

	public T orCondition(String condition) throws APIException {
		return addCriterion(true, condition);
	}

	public T orCondition(String condition, Object value) throws APIException {
		return addCriterion(true, condition, value);
	}

	protected abstract T addCriterion(boolean isOr, String condition) throws APIException;

	protected abstract T addCriterion(boolean isOr, String condition, Object value) throws APIException;

	protected abstract T addCriterion(boolean isOr, String condition, Object value1, Object value2) throws APIException;

	protected static Object enumv(Object value) throws APIException {
		if (value != null && value instanceof BaseEnum<?>) {
			return ((BaseEnum<?>) value).getKey();
		} else {
			return value;
		}
	}

	public boolean isVerify() throws APIException {
		return !criterionList.isEmpty();
	}

	public List<T> getCriterionList() {
		return criterionList;
	}

}
